package scoreCard.LivestockJudging3C;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.view.View;
import android.view.View.OnClickListener;
import android.util.Log;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaRecorder;
import android.media.MediaPlayer;
import android.media.MediaRecorder.OnInfoListener;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;

import java.io.File;
import java.io.IOException;

import scoreCard.LivestockJudging3C.R;

public class VoiceRecorderActivity extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);	
		setContentView(R.layout.recorder);
		recordButton = (Button) findViewById(R.id.recordButton);
		stopButton = (Button) findViewById(R.id.stopButton);
		saveButton = (Button) findViewById(R.id.saveButton);
		playButton = (Button) findViewById(R.id.playButton);
		
		setListeners();
		
		String extStorageDirectory = (Environment.getExternalStorageDirectory()+ "/3C/Competition").toString();
		File f = new File(extStorageDirectory);
		String[]CompNames = f.list();
		
		Bundle info = getIntent().getExtras();
		final AutoCompleteTextView compText = (AutoCompleteTextView) findViewById(R.id.recordCompName);
		ArrayAdapter<String> compadapter = new ArrayAdapter<String>(this, R.layout.list_item, CompNames);
		compText.setAdapter(compadapter);
		if (info != null) {
			mPlayFilePath = info.getString("path");	
			competitionName = info.getString("Parent");
			if(competitionName != null){
				compText.setText(info.getString("Parent"));
			}
		}
		if (mPlayFilePath != null) {
			playButton.setText(R.string.pause);
			final SeekBar seek = (SeekBar) findViewById(R.id.seekBar);
			startPlaying();
			progressThread = new ProgressThread(playerHandler);
	        progressThread.start();
	        recordButton.setEnabled(false);
			saveButton.setEnabled(false);
			playButton.setEnabled(true);
			stopButton.setEnabled(true);
			seek.setEnabled(true);
		}
	}

	@Override
	public void onPause() {
		super.onPause();
		if (mRecorder != null) {
			mRecorder.release();
			mRecorder = null;
		}

		if (mPlayer != null) {
			mPlayer.release();
			mPlayer = null;
		}
		recordButton.setEnabled(false);
		saveButton.setEnabled(false);
		playButton.setEnabled(true);
		stopButton.setEnabled(true);
	}

	@Override
	public Dialog onCreateDialog(int id) {
		switch (id) {
		case (SAVE_ERROR_DIALOG): {
			AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
			saveDialog.setMessage("You must enter a competition name before saving.");
			saveDialog.setPositiveButton("OK",
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							dialog.dismiss();
						}
					});
			return saveDialog.create();
		}
		}
		return null;
	}
    
	private void startPlaying() {
		mPlayer = new MediaPlayer();
		mPlayer.setOnCompletionListener(new OnCompletionListener() {
			public void onCompletion(MediaPlayer player) {
				player = null;
				stopPlaying();
			}
			
		});
		try {
			if (mPlayFilePath != null) {
				mPlayer.setDataSource(mPlayFilePath);
			} else {
				mPlayer.setDataSource(mFileName);
			}
			mPlayer.prepare();
			mPlayer.start();
		} catch (IOException e) {
			Log.e(LOG_TAG, "prepare() failed");
		}
	}

	private void stopPlaying() {
		if (mPlayer != null) {
			mPlayer.release();
			mPlayer = null;			
		}
		SeekBar seek = (SeekBar) findViewById(R.id.seekBar);
		seek.setProgress(0);
		playButton.setText(R.string.play);
		recordButton.setEnabled(true);
		saveButton.setEnabled(true);
		playButton.setEnabled(true);
		stopButton.setEnabled(false);
	}

	private void startRecording() {
		if (mRecorder == null) {
			mRecorder = new MediaRecorder();
			mRecorder.setOnInfoListener(new OnInfoListener() {

				public void onInfo(MediaRecorder recorder, int what, int extra) {
					if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
						stopRecording();
					}
					
				}
				
			});
		}
		mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
		mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
		mRecorder.setOutputFile(mFileName);
		mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setMaxDuration(RECORDING_MAX_LENGTH);
		try {
			mRecorder.prepare();
		} catch (IOException e) {
			Log.e(LOG_TAG, "prepare() failed");
		}
		mRecorder.start();
		this.recordingStartTime = System.currentTimeMillis();
	}

	private void stopRecording() {
		mRecorder.release();
		mRecorder = null;
	}
	
	private String getTimeString(int millis) {
	    StringBuffer buf = new StringBuffer();

	    int minutes = (millis % (1000*60*60)) / (1000*60);
	    int seconds = (( millis % (1000*60*60) ) % (1000*60)) / 1000;

	    buf.append(String.format("%2d", minutes)).append(":").append(String.format("%02d", seconds));

	    return buf.toString();
	}
	
	private void setListeners() {
		final SeekBar seek = (SeekBar) findViewById(R.id.seekBar);
		
		recordButton.setEnabled(true);
		saveButton.setEnabled(false);
		playButton.setEnabled(false);
		stopButton.setEnabled(false);
		seek.setEnabled(false);
		
		recordButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				if (mPlayer != null) {
					stopPlaying();
				}
				mPlayFilePath = null;
				startRecording();
				progressThread = new ProgressThread(recorderHandler);
		        progressThread.start();
				recordButton.setEnabled(false);
				saveButton.setEnabled(false);
				playButton.setEnabled(false);
				stopButton.setEnabled(true);
				seek.setEnabled(false);
			}
		});

		playButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				if (playButton.getText().equals(getString(R.string.play))) {
					playButton.setText(R.string.pause);
					if (mPlayer == null) {
						startPlaying();
						progressThread = new ProgressThread(playerHandler);
				        progressThread.start();
					} else {
						mPlayer.start();
					}
					recordButton.setEnabled(false);
				} else if (playButton.getText().equals(getString(R.string.pause))) {
					if (mPlayer != null && mPlayer.isPlaying()) {
						mPlayer.pause();
						playButton.setText(R.string.play);
						recordButton.setEnabled(true);
					}
				}
				stopButton.setEnabled(true);
				saveButton.setEnabled(false);
				seek.setEnabled(true);
			}
		});
		
		final Spinner spinnerClass = (Spinner) findViewById(R.id.spinnerClass);
		ArrayAdapter<CharSequence> classAdapter = ArrayAdapter.createFromResource(
				this, R.array.spinner_class,
				android.R.layout.simple_spinner_item);
		classAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		spinnerClass.setAdapter(classAdapter);
		
		Spinner detailSpinnerClass = (Spinner) findViewById(R.id.detailSpinnerClass);
		ArrayAdapter<CharSequence> detailClassAdapter = ArrayAdapter.createFromResource(
				this, R.array.detail_spinner_class,
				android.R.layout.simple_spinner_item);
		detailClassAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		detailSpinnerClass.setAdapter(detailClassAdapter);
		
		saveButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				EditText compText = (EditText) findViewById(R.id.recordCompName);
				String competitionName = compText.getText().toString(); 
				if (competitionName.equals("")) {
					showDialog(SAVE_ERROR_DIALOG);
				} else {
					EditText classText = (EditText) findViewById(R.id.classDesc);
					String classDescription = classText.getText().toString(); 
					if (classDescription != null && !classDescription.equals(""))
					{
						classDescription += " ";
					}
					Spinner classNameSpinner = (Spinner) findViewById(R.id.spinnerClass);
					Spinner detailNameSpinner = (Spinner)findViewById(R.id.detailSpinnerClass);
					String detailClass = detailNameSpinner.getSelectedItem().toString();
					String className = classNameSpinner.getSelectedItem().toString();
					if (className != null && !className.equals(""))
					{
						detailClass += " ";
					}
					SaveFile saveFile = new SaveFile();
					saveFile.SaveAudio(competitionName, classDescription + detailClass + className);
					Intent intent = new Intent(VoiceRecorderActivity.this, HistoryActivity.class);
					Bundle info = new Bundle();
					info.putString("Competition", competitionName);
					info.putString("Class", classDescription + detailClass + className);
					intent.putExtras(info);
					startActivity(intent);
				}
			}
		});
		
		
		stopButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				if (mRecorder != null) {
					stopRecording();
					recordButton.setEnabled(true);
					saveButton.setEnabled(true);
					playButton.setEnabled(true);
					stopButton.setEnabled(false);
				} else if (mPlayer != null) {
					stopPlaying();
				}
			}
		});
		
		seek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
				public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
					if (fromUser) {
						seek.setProgress(progress);
						if (mPlayer != null) {
							mPlayer.seekTo(progress);							
						}
					}
				}

				public void onStartTrackingTouch(SeekBar seekBar) {
					
				}

				public void onStopTrackingTouch(SeekBar seekBar) {
					
				}
		});
	}

	final Handler playerHandler = new Handler() {
        public void handleMessage(Message msg) {
        	SeekBar seek = (SeekBar) findViewById(R.id.seekBar);
            TextView elapsedTime = (TextView) findViewById(R.id.timeElapsedText);
        	if (mPlayer != null) {
        		seek.setMax(mPlayer.getDuration());
	        	seek.setProgress(mPlayer.getCurrentPosition());
	            elapsedTime.setText(getTimeString(mPlayer.getCurrentPosition()) + " /" + getTimeString(mPlayer.getDuration()));
        	} else {
        		elapsedTime.setText("");
            	progressThread.setState(ProgressThread.STATE_DONE);
        	}
        }
    };
    
    final Handler recorderHandler = new Handler() {
        public void handleMessage(Message msg) {
        	SeekBar seek = (SeekBar) findViewById(R.id.seekBar);
            TextView elapsedTime = (TextView) findViewById(R.id.timeElapsedText);
            long timeDiff = System.currentTimeMillis() - recordingStartTime;
        	if (mRecorder != null && timeDiff <= RECORDING_MAX_LENGTH) {
        		seek.setMax(RECORDING_MAX_LENGTH);
        		seek.setProgress((int) timeDiff);
        		elapsedTime.setText(getTimeString((int)timeDiff) + " /" + getTimeString(RECORDING_MAX_LENGTH));	
        	} else {
        		seek.setProgress(0);
	            elapsedTime.setText("");
				recordButton.setEnabled(true);
				saveButton.setEnabled(true);
				playButton.setEnabled(true);
				stopButton.setEnabled(false);
            	progressThread.setState(ProgressThread.STATE_DONE);
        	}
        }
    };
	private static final String LOG_TAG = "AudioRecordTest";
	private String mFileName = Environment.getExternalStorageDirectory()+"/3C/Temp/temp_reason.3gp";
	private String mPlayFilePath;
	private MediaRecorder mRecorder = null;
	private MediaPlayer mPlayer = null;
	private long recordingStartTime;
	private ProgressThread progressThread;
	private String competitionName;
	private Button recordButton;
	private Button stopButton;
	private Button saveButton;
	private Button playButton;
	

	private static final int SAVE_ERROR_DIALOG = 1;
	
	// in milliseconds
	private static final int RECORDING_MAX_LENGTH = 360000;
	
	private class ProgressThread extends Thread {
        Handler mHandler;
        final static int STATE_DONE = 0;
        final static int STATE_RUNNING = 1;
        int mState;
       
        ProgressThread(Handler h) {
            mHandler = h;
        }
       
        public void run() {
            mState = STATE_RUNNING; 
            while (mState == STATE_RUNNING) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Log.e("ERROR", "Thread Interrupted");
                }
                mHandler.sendEmptyMessage(0);
            }
        }
        
        /* sets the current state for the thread,
         * used to stop the thread */
        public void setState(int state) {
            mState = state;
        }
    }
}
